#include <sum_gpio.h>
#include <sum_rcu.h>
#include <sys_mem.h>

// RCU中将GPIO上电
static void _enable_gpio(void) {
	rcu_apb2_0_7_s apb2_0_7 = {
		.GPIOA = 1,
		.GPIOB = 1,
		.GPIOC = 1,
	};
	rcu_apb2_0_7_en_di(apb2_0_7);
}

// 配置GPIO的A1、A2、C13为输出
static void _setup_gpio_a1_a2_c13(void) {
	// 一次性配置A1和A2。引脚号1、2均不大于7，因此由CTL0配置。
	// 均配置为最普通的输出（通用、推挽、低速）。
	gpio_ctl_0_7_s gpioa_ctl_0_7 = {
		.pin1_ctl = GPIO_OUT_GP_PP_2MHZ,
		.pin2_ctl = GPIO_OUT_GP_PP_2MHZ,
	};
	gpio_setup_pin_0_7(GPIOA_Q, gpioa_ctl_0_7);

	// 配置C13。引脚号13大于7，因此由CTL1配置。配置为最普通的输出。
	gpio_ctl_8_15_s gpioc_ctl_8_15 = {
		.pin13_ctl = GPIO_OUT_GP_PP_2MHZ,
	};
	gpio_setup_pin_8_15(GPIOC_Q, gpioc_ctl_8_15);
}

// 配置GPIO的B11为上拉输入
static void _setup_gpio_b11(void) {
	// 配置B11为上/下拉输入
	gpio_ctl_8_15_s ctl = {
		.pin11_ctl = GPIO_IN_PULL,
	};
	gpio_setup_pin_8_15(GPIOB_Q, ctl);

	// 配置上/下拉模式为上拉
	gpio_pins_s pins = {
		.PIN11 = 1,
	};
	gpio_output_pull_high(GPIOB_Q, pins);
}

// 设置A1、A2的输出电平，其中A1的输出电平与B11的输入电平一致，A2的则相反。
static void _output_a1_a2(void) {
	// 将GPIOB整个port读出（这也是读GPIO的唯一方式）
	gpio_pins_s gpiob_input_pins = gpio_get_input_pins(GPIOB_Q);
	u32_s b11 = gpiob_input_pins.PIN11;

	// 需要设置的引脚号为1和2，因此mask中将pin_1和pin_2置1。
	// 其中引脚1与B11取值相同，引脚2相反。
	mask_pins_s mask_pins = {
		.mask.PIN1 = 1,
		.mask.PIN2 = 1,
		.pins.PIN1 = b11,
		.pins.PIN2 = !b11,
	};
	gpio_mask_set_pins(GPIOA_Q, mask_pins);
}

// 设置C13的输出电平
static void _output_c13(u32_s value) {
	gpio_set_one_output_pull_pin(GPIOC_Q, 13, value);
}

__attribute__((noreturn, section(".MAIN"))) void user_main(void) {
	// 未定义全局变量和静态局部变量，因此不需要scatter_load。
	// mem_scatter_load();
	_enable_gpio();
	_setup_gpio_a1_a2_c13();
	_setup_gpio_b11();
	u32_s i = 0;
	while (1) {
		_output_a1_a2();
		_output_c13((i >> 16) & 1);
		i++;
	}
}
